package cn.loioi.util.poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.loioi.util.poi.read.Feild;
import cn.loioi.util.poi.read.FeildType;
import cn.loioi.util.poi.read.ReadRow;
import cn.loioi.util.poi.util.ReadCellUtil;

/**
 * <br>
 * (c) Copyright 2016 by <br>
 * @description :excel 导入 <br>
 * @file_name :AbstractExcelImport.java <br>
 * @system_name :cmp-web <br>
 * @author :yyzh <br>
 * @创建时间 :2016年9月5日 下午1:19:26
 */
public abstract class AbstractExcelImport<T> {
	private Logger logger = LoggerFactory.getLogger(AbstractExcelImport.class);
	private int startRow = 0;
	private int endRow = 0;

	private Class<T> clazz;
	private List<Feild> feilds = new ArrayList<>();

	public AbstractExcelImport(Class<T> clazz) {
		this.clazz = clazz;
	}

	/**
	 * 开始导入
	 * @param filePath 表格文件路径
	 * @param sheetAt 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<ReadRow<T>> imported(String filePath, int sheetAt) throws Exception {
		List<ReadRow<T>> list = null;
		XSSFWorkbook xssfWorkbook = null;
		try {
			xssfWorkbook = new XSSFWorkbook(new FileInputStream(filePath));// 输出表格
			list = imported(xssfWorkbook.getSheetAt(sheetAt));
		} finally {
			if (xssfWorkbook != null) xssfWorkbook.close();
		}
		return list;
	}

	/**
	 * 开始导入
	 * @param file 表格文件
	 * @param sheetAt 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<ReadRow<T>> imported(File file, int sheetAt) throws Exception {
		List<ReadRow<T>> list = null;
		XSSFWorkbook xssfWorkbook = null;
		try {
			xssfWorkbook = new XSSFWorkbook(new FileInputStream(file));// 输出表格
			list = imported(xssfWorkbook.getSheetAt(sheetAt));
		} finally {
			if (xssfWorkbook != null) xssfWorkbook.close();
		}
		return list;
	}

	/**
	 * 开始导入
	 * @param inputStream 表格文件流
	 * @param sheetAt 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<ReadRow<T>> imported(InputStream inputStream, int sheetAt) throws Exception {
		List<ReadRow<T>> list = null;
		XSSFWorkbook xssfWorkbook = null;
		try {
			xssfWorkbook = new XSSFWorkbook(inputStream);// 输出表格
			list = imported(xssfWorkbook.getSheetAt(sheetAt));
		} finally {
			if (xssfWorkbook != null) xssfWorkbook.close();
		}
		return list;
	}

	/**
	 * 开始导入
	 * @param xssfSheet 工作簿
	 * @return
	 * @throws Exception
	 */
	public List<ReadRow<T>> imported(XSSFSheet xssfSheet) throws Exception {
		List<ReadRow<T>> list = new ArrayList<>();
		if (endRow == 0) endRow = xssfSheet.getLastRowNum();// 待读取的最后一条
		/* 循环读取数据 */
		for (int i = startRow; i <= endRow; i++) {
			XSSFRow xssfRow = xssfSheet.getRow(i);// 获取行
			if (xssfRow == null) continue;
			logger.debug("正在读取{}行...", i);
			ReadRow<T> readRow = ReadRow.newInstance(i, clazz);// 实例化返回值
			/* 读取数据 */
			for (Feild feild : feilds) {
				try {
					if (feild.getType() == FeildType.INEGER) {
						readRow.set(feild.getName(), ReadCellUtil.getInteger(xssfRow, feild.getIndex()));
					} else if (feild.getType() == FeildType.FLOAT) {
						readRow.set(feild.getName(), ReadCellUtil.getFloat(xssfRow, feild.getIndex()));
					} else if (feild.getType() == FeildType.BOOLEAN) {
						readRow.set(feild.getName(), ReadCellUtil.getBoolean(xssfRow, feild.getIndex()));
					} else if (feild.getType() == FeildType.DATE) {
						readRow.set(feild.getName(), ReadCellUtil.getDate(xssfRow, feild.getIndex()));
					} else {
						readRow.set(feild.getName(), ReadCellUtil.getString(xssfRow, feild.getIndex()));
					}
				} catch (Exception e) {
					readRow.addError(feild.getIndex(), ReadCellUtil.getString(xssfRow, feild.getIndex()), e.getMessage());
				}
			}
			list.add(readRow);
		}
		return list;
	}

	/**
	 * 获取读取起始行
	 * @return
	 */
	public int getStartRow() {
		return startRow;
	}

	/**
	 * 设置读取起始行
	 * @param startRow
	 */
	public void setStartRow(int startRow) {
		this.startRow = startRow;
	}

	/**
	 * 获取读取终止行
	 * @return
	 */
	public int getEndRow() {
		return endRow;
	}

	/**
	 * 设置读取终止行
	 * @param endRow
	 */
	public void setEndRow(int endRow) {
		this.endRow = endRow;
	}

	/**
	 * 添加需要的字段
	 * @param index
	 * @param name
	 * @return
	 */
	public AbstractExcelImport<T> addFeild(int index, String name) {
		return addFeild(index, name, FeildType.STRING);
	}

	/**
	 * 添加需要的字段
	 * @param index
	 * @param name
	 * @param type
	 * @return
	 */
	public AbstractExcelImport<T> addFeild(int index, String name, FeildType type) {
		feilds.add(new Feild(index, name, type));
		return this;
	}

}
